package com.caochenlei.codebuilder.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

import com.caochenlei.codebuilder.entity.Column;
import com.caochenlei.codebuilder.entity.Table;
import com.caochenlei.codebuilder.entity.Template;

public class TemplateUtil {

    /**
     * 功能说明：判断模板文件是否需要渲染
     *
     * @param fileName
     * @return
     */
    public static boolean isRenderFile(String fileName) {
        String extendedName = FileUtil.getExtendedName(fileName);
        if (extendedName.contains("htm")) {
            return true;
        }
        if (extendedName.contains("html")) {
            return true;
        }
        if (extendedName.contains("yml")) {
            return true;
        }
        if (extendedName.contains("yaml")) {
            return true;
        }
        if (extendedName.contains("xml")) {
            return true;
        }
        if (extendedName.contains("properties")) {
            return true;
        }
        if (extendedName.contains("java")) {
            return true;
        }
        if (extendedName.contains("jsp")) {
            return true;
        }
        if (extendedName.contains("component")) {
            return true;
        }
        if (extendedName.contains("project")) {
            return true;
        }
        if (extendedName.contains("md")) {
            return true;
        }
        if (extendedName.contains("(TFILE)")) {
            return true;
        }
        return false;
    }

    /**
     * 功能说明：判断文件名是否包含表关键字
     *
     * @param fileName
     * @return
     */
    public static boolean isContainsParams(String fileName) {
        List<String> params = ReflectUtil.parse(Table.class, new String[]{"columns"});
        for (String param : params) {
            if (fileName.contains(param)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 功能说明：获取所有的模板名称
     *
     * @return
     */
    public static List<String> getAllTemplateNames() {
        List<String> list = new ArrayList<String>();
        File file = new File(System.getProperty("user.dir") + "\\template");
        File[] listFiles = file.listFiles();
        for (File f : listFiles) {
            list.add(f.getName());
        }
        return list;
    }

    /**
     * 功能说明：根据模板名称获取模板地址
     *
     * @param templateName
     * @return
     */
    public static String getAbsolutePathByTemplateName(String templateName) {
        File file = new File(System.getProperty("user.dir") + "\\template");
        File[] listFiles = file.listFiles();
        for (File f : listFiles) {
            if (f.getName().equals(templateName)) {
                return f.getAbsolutePath();
            }
        }
        return null;
    }

    /**
     * 功能说明：获取所有模板文件
     *
     * @param templateBasePath
     * @return
     */
    public static List<Template> getAllTemplateFiles(String templateBasePath) {
        return loadAllTemplateFiles(templateBasePath, new File(templateBasePath));
    }

    /**
     * 功能说明：加载所有模板文件
     *
     * @param templateBasePath
     * @param dir
     * @return
     */
    public static List<Template> loadAllTemplateFiles(String templateBasePath, File dir) {
        List<Template> templates = new ArrayList<Template>();

        File[] listFiles = dir.listFiles();
        if (listFiles != null) {
            for (File file : listFiles) {
                Template template = new Template();
                template.setName(file.getName());
                template.setAbsolutePath(file.getAbsolutePath());
                template.setRelativePath(file.getParent().replace(templateBasePath, ""));

                if (file.isDirectory()) {
                    templates.addAll(loadAllTemplateFiles(templateBasePath, file));
                } else {
                    templates.add(template);
                }
            }
        }

        return templates;
    }

    /**
     * 功能说明：获取所有模板文件
     *
     * @param templateConfigPath
     * @return
     */
    public static Map<String, String> getAllTemplateConfigs(String templateConfigPath) {
        return loadAllTemplateConfigs(templateConfigPath, new File(templateConfigPath));
    }

    /**
     * 功能说明：加载所有模板文件
     *
     * @param templateConfigPath
     * @param dir
     * @return
     */
    public static Map<String, String> loadAllTemplateConfigs(String templateConfigPath, File dir) {
        Map<String, String> map = new HashMap<String, String>();
        File[] listFiles = dir.listFiles();
        if (listFiles != null) {
            for (File file : listFiles) {
                file = new File(file.getAbsolutePath());
                if (file.isDirectory()) {
                    map.putAll(loadAllTemplateConfigs(templateConfigPath, file));
                } else {
                    map.put(file.getName(), FileUtil.getContent(file.getAbsolutePath()));
                }
            }
        }
        return map;
    }

    /**
     * 功能说明：替换全局变量
     *
     * @param oldContent
     * @param map
     * @return
     */
    public static String createContentForGobal(String oldContent, Map<String, String> map) {
        for (String key : map.keySet()) {
            oldContent = oldContent.replace("[" + key + "]", map.get(key));
        }
        return oldContent;
    }

    /**
     * 功能说明：替换表级变量
     *
     * @param oldContent
     * @param map
     * @param tables
     * @return
     */
    public static String createContentForTable(String oldContent, Map<String, String> map, List<Table> tables) {
        for (String tableTemplateFileName : map.keySet()) {
            String tableTemplateFileSymbol = "<" + tableTemplateFileName + ">";
            if (oldContent.contains(tableTemplateFileSymbol)) {
                String tableTemplateFileContent = map.get(tableTemplateFileName);
                StringBuilder sb = new StringBuilder();
                for (Table table : tables) {
                    sb.append(ReflectUtil.assignment(tableTemplateFileContent, ReflectUtil.parse(Table.class, new String[]{"columns"}), table));
                }
                oldContent = oldContent.replace(tableTemplateFileSymbol, sb.toString());
            }
        }
        return oldContent;
    }

    /**
     * 功能说明：替换列级变量
     *
     * @param oldContent
     * @param map
     * @param table
     * @return
     */
    public static String createContentForColumn(String oldContent, Map<String, String> map, Table table) {
        // 循环所有子替换符
        for (String columnTemplateFileName : map.keySet()) {
            String columnTemplateFileSymbol = "<" + columnTemplateFileName + ">";
            if (oldContent.contains(columnTemplateFileSymbol)) {
                String columnTemplateFileContent = map.get(columnTemplateFileName);
                StringBuilder sb = new StringBuilder();

                for (Column column : table.getColumns()) {
                    try {
                        boolean flag = true;

                        // 只循环主键
                        if (columnTemplateFileName.indexOf(".key") >= 0) {
                            if (!column.getIsPrimaryKey()) {
                                flag = false;
                            }
                        }

                        // 只循环非主键
                        if (columnTemplateFileName.indexOf(".nokey") >= 0) {
                            if (column.getIsPrimaryKey()) {
                                flag = false;
                            }
                        }

                        // 只循环唯一键
                        if (columnTemplateFileName.indexOf(".uni") >= 0) {
                            if (!column.getIsUniqueKey()) {
                                flag = false;
                            }
                        }

                        // 只循环非唯一键
                        if (columnTemplateFileName.indexOf(".nouni") >= 0) {
                            if (column.getIsUniqueKey()) {
                                flag = false;
                            }
                        }

                        // 只循环String类型
                        if (columnTemplateFileName.indexOf(".String") >= 0) {
                            if (!column.getColumnLanguageType().equals("String")) {
                                flag = false;
                            }
                        }

                        // 只循环Short类型
                        if (columnTemplateFileName.indexOf(".Short") >= 0) {
                            if (!column.getColumnLanguageType().equals("Short")) {
                                flag = false;
                            }
                        }

                        // 只循环Integer类型
                        if (columnTemplateFileName.indexOf(".Integer") >= 0) {
                            if (!column.getColumnLanguageType().equals("Integer")) {
                                flag = false;
                            }
                        }

                        // 只循环Long类型
                        if (columnTemplateFileName.indexOf(".Long") >= 0) {
                            if (!column.getColumnLanguageType().equals("Long")) {
                                flag = false;
                            }
                        }

                        // 只循环Float类型
                        if (columnTemplateFileName.indexOf(".Float") >= 0) {
                            if (!column.getColumnLanguageType().equals("Float")) {
                                flag = false;
                            }
                        }

                        // 只循环Double类型
                        if (columnTemplateFileName.indexOf(".Double") >= 0) {
                            if (!column.getColumnLanguageType().equals("Double")) {
                                flag = false;
                            }
                        }

                        // 只循环Boolean类型
                        if (columnTemplateFileName.indexOf(".Boolean") >= 0) {
                            if (!column.getColumnLanguageType().equals("Boolean")) {
                                flag = false;
                            }
                        }

                        // 只循环Date类型
                        if (columnTemplateFileName.indexOf(".Date") >= 0) {
                            if (!column.getColumnLanguageType().equals("java.util.Date")) {
                                flag = false;
                            }
                            if (!column.getColumnLanguageType().equals("java.time.LocalDateTime")) {
                                flag = false;
                            }
                        }

                        // 根据模板生成内容
                        if (flag) {
                            sb.append(ReflectUtil.assignment(columnTemplateFileContent, ReflectUtil.parse(Column.class, new String[]{"isPrimaryKey", "isUniqueKey"}), column));
                        }
                    } catch (Exception e) {
                        JOptionPane.showMessageDialog(null, table.getTableName() + "表列字段与编程语言数据类型不对应，请补充后重新生成代码！", "温馨提示", JOptionPane.ERROR_MESSAGE);
                        e.printStackTrace();
                    }
                }

                //特殊替换符处理
                if (sb.toString().length() > 2) {
                    //去掉最后换行
                    sb.deleteCharAt(sb.length() - 1);
                    sb.deleteCharAt(sb.length() - 1);

                    //插入一个换行
                    if (sb.toString().contains("[newLine]")) {
                        sb = new StringBuilder(sb.toString().replace("[newLine]", "\r\n"));
                    }

                    //去掉所有换行
                    if (sb.toString().contains("[nowrap]")) {
                        sb = new StringBuilder(sb.toString().replace("[nowrap]", "").replace("\r\n", ""));
                    }

                    //删除最后一个字符
                    if (sb.toString().contains("[deleteCharAtLastOne]")) {
                        sb = new StringBuilder(sb.toString().replace("[deleteCharAtLastOne]", ""));
                        sb.deleteCharAt(sb.length() - 1);
                    }

                    //删除最后两个字符
                    if (sb.toString().contains("[deleteCharAtLastTwo]")) {
                        sb = new StringBuilder(sb.toString().replace("[deleteCharAtLastTwo]", ""));
                        sb.deleteCharAt(sb.length() - 1);
                        sb.deleteCharAt(sb.length() - 1);
                    }
                }

                oldContent = oldContent.replace(columnTemplateFileSymbol, sb.toString());
            }
        }

        return ReflectUtil.assignment(oldContent, ReflectUtil.parse(Table.class, new String[]{"columns"}), table);
    }

}
